﻿#define  _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string>
#include<stdlib.h>
#include<windows.h>//系统工具库
#include<iostream>
#include<iomanip>
#include<fstream>

using namespace std;

#define OK 1
#define ERROR 0
#define OVERFLOW -1

typedef int ET;//值类型重定义

typedef struct SP
{
	ET* top;//栈顶
	int size;//当前栈数
	int space;//容量
	ET* bottom;//栈底
}ST;

void menu()
{
	printf("****************************\n");
	printf("*    顺序栈的表现与实现    *\n");
	printf("****************************\n"); 
	printf("*1.元素入栈      2.元素出栈*\n");
	printf("*3.全部弹出      4.显示栈顶*\n");
	printf("*5.显示栈数      0.退出程序*\n");
	printf("****************************\n");
}

int InitStack(ST* L)//初始化
{
	L->top = L->bottom= NULL;//栈顶等于栈底
	L->space = L->size = 0;//栈数和容量为空
	return OK;
}

int StackCheckCapacity(ST *L)//顺序栈的动态内存开辟
{
	if ((L->space) == (L->size) )//若栈长等于容量且数据数量也等于容量就扩容
	{
		int spaces = (L->space) == 0 ? 4 : (L->space) * 2;//容量翻倍，初次为4
		ET* tops = (ET*)realloc(L->top, spaces * sizeof(ET));//对栈顶的内存进行加长，加长栈顶的可用地址长度
		if (tops == NULL)//若新地址为空
		{
			printf("realloc fail\n");
			exit(OVERFLOW);
		}
		else
		{
			L->top = tops;//交付开辟新地址
			L->space = spaces;//交付新容量大小
		}
	}
	return OK;
}


int StackDestroy(ST* L)//销毁栈
{
	if (L->top==NULL)//空栈
	{
		exit(OVERFLOW);//直接退出，报空
	}
	free(L->top);//释放栈顶所占空间
	L->top = NULL;//栈顶置空
	L->size = L->space = 0;//容量置空
	return OK;
}


int StackPush(ST* L,ET x)//入栈
{
	if ((L->space) == (L->size))//若栈满
	{
		StackCheckCapacity(L);//开辟空间
	}
	L->top[L->size] = x;
	L->size++;

	return OK;
}


int StackPop(ST* L)//出栈
{
	if ((L->size) > 0)
	{
		printf("%d出栈\n",L->top[L->size-1]);
		L->size--;//数据减一
		return OK;
	}
	else
	{
		return ERROR;
	}
	
}


int Stacktop(ST* L)//输出栈顶
{
	if ((L->size) > 0)
	{
		return L->top[L->size - 1];
	}
	return OVERFLOW;
}


int  StackPrint(ST* L)//弹出栈的所有元素
{
	while (L->size)//如果size不为0
	{
		StackPop(L);
		//printf("%d\n",L->top[L->size-1]);//打印当前被弹元素
		//L->size--;//栈减一
	}
	if (L->size == 0)
	{
		printf("栈空！\n");//打完输出栈空
	}
	return OK;
}

int main()
{
	ST sl;
	InitStack(&sl);//初始化
	int order = 0;
	do
	{
		system("cls");
		StackCheckCapacity(&sl);//检查增容
		menu();
		printf("请输入功能>");
		scanf("%d",&order);
		switch (order)
		{
			case 0://退出
			{
				printf("退出成功！\n");
				StackDestroy(&sl);
				break;
			}

			case 1://入栈
			{
				int sum = 0;
				printf("请输入入栈元素>");
				scanf("%d",&sum);
				StackPush(&sl,sum);
				printf("%d入栈成功\n",sum);
				system("pause");
				break;
			}
			
			case 2://出栈
			{
				int sum = StackPop(&sl);
				if ( sum == ERROR)
				{
					printf("栈空！\n");
				}
				system("pause");
				break;
			}

			case 3://显示栈顶
			{
				StackPrint(&sl);
				system("pause");
				break;
			}

			case 4://全部弹出
			{
				int sum = Stacktop(&sl);
				if (sum == (OVERFLOW))
				{
					printf("栈空！\n");
				}
				else
				{
					printf("栈顶为：%d\n",sum );
				}
				system("pause");
				break;
			}

			case 5://显示栈数
			{
				ST* p = &sl;
				printf("当前栈数：%d\n",p->size);
				system("pause");
				break;
			}
			
			default:
			{
				printf("输入错误！\n");
				system("pause");
				break;
			}
		}

	} while (order);
	
	return OK;
}